package com.sfh.base;

import android.util.SparseArray;

import rx.Observable;
import rx.Subscriber;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
import rx.schedulers.Schedulers;

/**
 * 功能描述: Retrofit 处理
 *
 * @date 2017/7/19
 */
public final class RetrofitManager {


    SparseArray<Subscription> serverList = new SparseArray<>(5);

    /***
     * 取消业务层监听
     */
    public void unSubscribe(int taskId) {

        Subscription subscription = serverList.get(taskId);
        if (subscription != null && !subscription.isUnsubscribed()) {
            subscription.unsubscribe();
        }
    }

    /***
     * 添加业务层监听
     */
    public void putSubscribe(int taskId, Subscription subscription) {
        this.unSubscribe(taskId);
        serverList.put(taskId, subscription);
    }

    /***
     * 取消业务层监听
     */
    public void unSubscribeAll() {

        int size = serverList.size();
        for (int i = 0; i < size; i++) {
            Subscription subscription = serverList.valueAt(i);
            if (null != subscription && !subscription.isUnsubscribed()){
                subscription.unsubscribe();
            }
        }
    }

    /***
     * 异步请求操作
     * @param observable
     * @param subscriber
     * @param <T>
     * @return
     */
    public static <T> Subscription execute(Observable<T> observable, Subscriber<T> subscriber) {

        return observable.compose(schedulersTransformer())
                .subscribe(subscriber);
    }

    private static Observable.Transformer schedulersTransformer() {

        return new Observable.Transformer() {


            @Override
            public Object call(Object observable) {

                return ((Observable) observable).subscribeOn(Schedulers.io())
                        .unsubscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread()).onErrorResumeNext(new HttpResponseFunc<>());
            }
        };
    }

    private static class HttpResponseFunc<T> implements Func1<Throwable, Observable<T>> {

        @Override
        public Observable<T> call(Throwable throwable) {

            if (throwable == null) {
                return Observable.error(new RuntimeException("throwable  is mull"));
            }

            try {
                return Observable.error(new RuntimeException(throwable));
            } catch (Exception e) {
                return Observable.error(new RuntimeException(e));
            }
        }
    }
}
